package cn.jji8.createX.function.fill;

import cn.jji8.createX.Main;
import cn.jji8.createX.function.fill.canPlaceBlock.FillCanPlaceBlock;
import cn.jji8.createX.function.fill.canPlaceBlock.FillCanPlaceBlockState;
import cn.jji8.createX.manipulate.Selector;
import cn.jji8.createX.manipulate.SelectorImplement;
import cn.jji8.patronSaint.quick.boxesMenu.CanSaveClickImplement;
import cn.jji8.patronSaint.quick.boxesMenu.MenuManger;
import cn.jji8.patronSaint.quick.vision.VisionTool;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitTask;

import java.util.ArrayList;
import java.util.List;

public class FillManger implements CanSaveClickImplement, SelectorImplement {
    //最大距离
    public static int MaxDistance = 100;
    //被填充的方法
    Material fillBookMaterial = Material.AIR;
    //对应的menu
    final MenuManger menu;
    //选择点
    Location spot1 = null ,spot2 = null;
    //填充工具
    ItemStack miningTools = new ItemStack(Material.AIR);
    //填充控制器
    FillCanPlaceBlockState fillCanPlaceBlockState = null;
    //是否被显示正在填充
    boolean displayFillProgress = false;
    //被打开
    boolean isopen = false;
    //最大距离

    /**
     * 获取即将填充方块Material
     * */
    @SuppressWarnings("unused")
    public Material getFillBookMaterial() {
        return fillBookMaterial;
    }
    /**
     * 设置即将填充方块Material
     * */
    public void setFillBookMaterial(Material fillBookMaterial) {
        this.fillBookMaterial = fillBookMaterial==null ? Material.AIR : fillBookMaterial;
    }

    /**
     * @param menu 控制器所在的 MenuManger
     * */
    @SuppressWarnings("unused")
    FillManger(MenuManger menu){
        this.menu = menu;
    }
    /**
     * 扣除对应的物品
     * @return 成功true 没有物品false
     * */
    public boolean buckle(Material material){
        if(material.equals(Material.AIR)){
            return true;
        }
        for(int i=0;i<45;i++){
           ItemStack itemStack = menu.getItem(i);
           if(itemStack!=null){
               if(itemStack.getType().equals(material)){
                   itemStack.setAmount(itemStack.getAmount()-1);
                   menu.setItem(i,itemStack);
                   return true;
               }
           }
        }
        return false;
    }

    /**
     * 处理点击事件的方法，实现后由MenuManger调用
     *
     */
    @Override
    public void click(InventoryClickEvent e) {
        e.setCancelled(true);
        if(!(e.getWhoClicked() instanceof Player)){//排除不是玩家的点击
            return;
        }

        Player player = (Player) e.getWhoClicked();
        SelectorImplement selectorImplement = Selector.getPlayerSelectorimplement((Player) e.getWhoClicked());//获取玩家之前的操作处理器

        //当选择控制器不是自己时
        if(selectorImplement!=this){
            Selector.setPlayerSelectorimplement(player,this);
            open(player,menu.getMenu(),e.getRawSlot());
            return;
        }

        //正在填充时
        if(fillCanPlaceBlockState!=null){
            if((!fillCanPlaceBlockState.isComplete())&(!fillCanPlaceBlockState.isCancel())){
                fillCanPlaceBlockState.setCancel(true);
                open(player,menu.getMenu(),e.getRawSlot());
                return;
            }
        }
        //被显示正在填充时
        if(displayFillProgress){
            open(player,menu.getMenu(),e.getRawSlot());
            return;
        }


        //当两点已选择时
        if(spot1!=null&spot2!=null){
            //当距离小于MaxDistance格时
            if(!(spot1.distance(player.getLocation())>=MaxDistance|spot2.distance(player.getLocation())>=MaxDistance)){

                //开始填充
                fillCanPlaceBlockState = FillCanPlaceBlock.fill(player,fillBookMaterial,spot1,spot2,this);
                player.closeInventory();
            }
        }
    }
    BukkitTask bukkitTask =null;
    BukkitTask bukkitTask1 =null;
    /**
     * 对应的玩家与方块交互时被调用
     */
    @Override
    public void PlayerInteractEvent(PlayerInteractEvent e) {
        ItemStack itemStack = e.getItem();
        //手上没东西，排除
        if(itemStack==null){
            return;
        }
        //手上不是小斧头，排除
        if(!itemStack.getType().equals(Material.WOODEN_AXE)){
            return;
        }
        
        //选择点
        e.setCancelled(true);
        if(e.getClickedBlock()!=null){
            if(e.getAction().equals(Action.LEFT_CLICK_BLOCK)){
                spot1 = e.getClickedBlock().getLocation();
                ItemStack itemStack1 = new ItemStack(e.getClickedBlock().getType());
                ItemMeta ItemMeta = itemStack1.getItemMeta();
                assert ItemMeta != null;
                ItemMeta.setDisplayName("§d点1   §e(X="+spot1.getBlockX()+" Y="+spot1.getBlockY()+" Z="+spot1.getBlockZ()+")");
                itemStack1.setItemMeta(ItemMeta);
                menu.setItem(45,itemStack1);
                e.getPlayer().sendTitle("§a已选择点1","§e(X="+spot1.getBlockX()+" Y="+spot1.getBlockY()+" Z="+spot1.getBlockZ()+")",0,0,20);
            }else if(e.getAction().equals(Action.RIGHT_CLICK_BLOCK)){
                spot2 = e.getClickedBlock().getLocation();
                ItemStack itemStack1 = new ItemStack(e.getClickedBlock().getType());
                ItemMeta ItemMeta = itemStack1.getItemMeta();
                assert ItemMeta != null;
                ItemMeta.setDisplayName("§d点2   §e(X="+spot2.getBlockX()+" Y="+spot2.getBlockY()+" Z="+spot2.getBlockZ()+")");
                itemStack1.setItemMeta(ItemMeta);
                menu.setItem(53,itemStack1);
                e.getPlayer().sendTitle("§a已选择点2","§e(X="+spot1.getBlockX()+" Y="+spot1.getBlockY()+" Z="+spot1.getBlockZ()+")",0,0,20);
            }
        }
        //显示粒子效果
        if(spot1!=null&spot2!=null){
            if(bukkitTask!=null){
                bukkitTask.cancel();
            }
            if(bukkitTask1!=null){
                bukkitTask1.cancel();
            }
            bukkitTask = Bukkit.getScheduler().runTaskTimerAsynchronously(Main.getMain(), () -> VisionTool.rectangle(e.getPlayer(),Particle.FLAME,spot1,spot2),0,10);
            bukkitTask1 = Bukkit.getScheduler().runTaskLaterAsynchronously(Main.getMain(), () -> bukkitTask.cancel(),20*60);
        }
    }

    @Override
    public void open(Player player, Inventory inventory,int a) {
        isopen = true;
        refreshMiningTools();
        displayFillProgress = false;
        SelectorImplement selectorImplement = Selector.getPlayerSelectorimplement(player);//获取玩家之前的操作处理器
        if(selectorImplement!=this){
            ItemStack itemStack = new ItemStack(Material.MAGENTA_WOOL);
            ItemMeta itemMeta = itemStack.getItemMeta();
            assert itemMeta != null;
            itemMeta.setDisplayName("§d填充工具（未激活）");
            ArrayList<String> lore = new ArrayList<>();
            lore.add("§e点击激活填充工具");
            lore.add("");
            lore.add("--------------------------------");
            lore.add("§g帮助:");
            lore.add("§g1.激活激活填充工具       §a<<--当前步骤.");
            lore.add("§g2.选择需要填充的区域");
            lore.add("§g3.开始填充");
            itemMeta.setLore(lore);
            itemStack.setItemMeta(itemMeta);
            menu.setItem(a,itemStack);
            return;
        }
        if(spot1!=null&spot2!=null){
            if(spot1.distance(player.getLocation())>=MaxDistance|spot2.distance(player.getLocation())>=MaxDistance){
                ItemStack itemStack = new ItemStack(Material.YELLOW_WOOL);
                ItemMeta itemMeta = itemStack.getItemMeta();
                assert itemMeta != null;
                itemMeta.setDisplayName("§d填充选中的区域 (§e你距离填充点太远，不能填充§d)");
                ArrayList<String> lore = new ArrayList<>();
                lore.add("§a距离点1: §e"+(int)spot1.distance(player.getLocation()));
                lore.add("§a距离点2: §e"+(int)spot2.distance(player.getLocation()));
                lore.add("§e两者均需小于"+MaxDistance+"格。");
                lore.add("");
                lore.add("--------------------------------");
                lore.add("§g帮助:");
                lore.add("§g1.激活激活填充工具");
                lore.add("§g2.选择需要填充的区域");
                lore.add("§g3.开始填充         §a<<--当前步骤.");
                itemMeta.setLore(lore);
                itemStack.setItemMeta(itemMeta);
                menu.setItem(a,itemStack);
                Selector.setPlayerSelectorimplement(player,this);
                return;
            }
            if(fillCanPlaceBlockState!=null){
                if((!fillCanPlaceBlockState.isComplete())&(!fillCanPlaceBlockState.isCancel())){
                    displayFillProgress = true;
                    ItemStack itemStack = new ItemStack(Material.YELLOW_WOOL);
                    ItemMeta itemMeta = itemStack.getItemMeta();
                    assert itemMeta != null;
                    itemMeta.setDisplayName("§d取消填充");
                    ArrayList<String> lore = new ArrayList<>();
                    lore.add("§e需要开始新的填充，请取消掉当前填充。");
                    lore.add("");
                    lore.add("--------------------------------");
                    lore.add("§g帮助:");
                    lore.add("§g1.激活激活填充工具");
                    lore.add("§g2.选择需要填充的区域");
                    lore.add("§g3.开始填充         §a<<--当前步骤.");
                    itemMeta.setLore(lore);
                    itemStack.setItemMeta(itemMeta);
                    menu.setItem(a,itemStack);
                    Selector.setPlayerSelectorimplement(player,this);
                    return;
                }
            }
            ItemStack itemStack = new ItemStack(Material.LIME_WOOL);
            ItemMeta itemMeta = itemStack.getItemMeta();
            assert itemMeta != null;
            itemMeta.setDisplayName("§d填充选中的区域");
            ArrayList<String> lore = new ArrayList<>();
            lore.add("§e点击填充选中区域");
            lore.add("");
            lore.add("--------------------------------");
            lore.add("§g帮助:");
            lore.add("§g1.激活区域选择器");
            lore.add("§g2.选择需要填充的区域");
            lore.add("§g3.开始填充         §a<<--当前步骤.");
            itemMeta.setLore(lore);
            itemStack.setItemMeta(itemMeta);
            menu.setItem(a,itemStack);
            return;
        }
        ItemStack itemStack = new ItemStack(Material.MAGENTA_WOOL);
        ItemMeta itemMeta = itemStack.getItemMeta();
        assert itemMeta != null;
        itemMeta.setDisplayName("§d请使用工具选择需要填充的位置");
        ArrayList<String> lore = new ArrayList<>();
        lore.add("§e使用工具左键选择点1");
        lore.add("§e使用工具右键选择点2");
        lore.add("");
        lore.add("--------------------------------");
        lore.add("§g帮助:");
        lore.add("§g1.激活区域选择器");
        lore.add("§g2.选择需要填充的区域    §a<<--当前步骤.");
        lore.add("§g3.开始填充");
        itemMeta.setLore(lore);
        itemStack.setItemMeta(itemMeta);
        menu.setItem(a,itemStack);
    }

    @Override
    public void close(Player player, Inventory inventory, int i) {
        isopen = false;
    }

    long tiemrefreshMiningToolsSSSSS = 0;
    /**
     * 疯狂的刷新填充工具，只有在玩家打开时刷新
     * */
    public void refreshMiningToolsSSSSS(){
        if(isopen){
            if(tiemrefreshMiningToolsSSSSS+500<System.currentTimeMillis()){
                refreshMiningTools();
            }
        }
    }

    /**
     * 刷新填充工具
     * */
    public void refreshMiningTools(){
        ItemStack itemStack1 = new ItemStack(this.getMiningTools());
        if(itemStack1.getType().equals(Material.AIR)){
            itemStack1 = new ItemStack(Material.WOODEN_PICKAXE);
            ItemMeta itemMeta1 = itemStack1.getItemMeta();
            assert itemMeta1 != null;
            itemMeta1.setDisplayName("§d(无挖掘工具)");
            List<String> list = itemMeta1.getLore();
            if(list==null){
                list = new ArrayList<>();
            }
            list.add("§g将挖掘工具放到此处");
            itemMeta1.setLore(list);
            itemStack1.setItemMeta(itemMeta1);
        }else {
            ItemMeta itemMeta1 = itemStack1.getItemMeta();
            assert itemMeta1 != null;
            List<String> list = itemMeta1.getLore();
            if(list==null){
                list = new ArrayList<>();
            }
            list.add("§g（将使用此挖掘工具）");
            itemMeta1.setLore(list);
            itemStack1.setItemMeta(itemMeta1);
        }
        menu.setItem(47,itemStack1);
        menu.setItem(51,itemStack1);
    }
    public ItemStack getMiningTools() {
        return miningTools;
    }
    public void setMiningTools(ItemStack miningTools){
        this.miningTools = miningTools;
    }

    /**
     * 由CanSavedMenuManger调用此方法，将需要保存的数据写入yamlConfiguration即可
     */
    @Override
    public void Save(YamlConfiguration yamlConfiguration) {
        yamlConfiguration.set("miningTools",miningTools);
    }

    /**
     * 由CanSavedMenuManger调用此方法，从yamlConfiguration中加载需要的数据即可，一般在被设置进去的时候被调用
     */
    @Override
    public void load(YamlConfiguration yamlConfiguration) {
        ItemStack itemStack = yamlConfiguration.getItemStack("miningTools");
        if(itemStack!=null){
            miningTools = itemStack;
        }
    }
}
